A programmable logic device is designed to be user programmable so that users may implement logic designs of their choices. One type of programmable logic device is the Complex Programmable Logic Device (CPLD). A CPLD includes two or more “function blocks” having a two-level AND/OR structure connected together and to input/output (I/O) resources by an interconnect switch matrix. Another type of programmable logic device is a field programmable gate array (FPGA). In a typical FPGA, an array of configurable logic blocks (CLBs) is coupled to programmable input/output blocks (IOBs). The CLBs and IOBs are interconnected by a hierarchy of programmable routing resources. For both of these types of programmable logic devices, the functionality of the device is controlled by configuration data bits of a configuration bitstream provided to the device for that purpose. The configuration data bits may be stored in volatile memory (e.g., static memory cells, as in FPGAs and some CPLDs), in non-volatile memory (e.g., FLASH memory, as in some CPLDs), or in any other type of memory cell.
PLDs also have different “modes” depending on the operations being performed on them. A specific protocol allows a programmable logic device to enter into the appropriate mode. Typical PLDs have internal blocks of configuration memory which specify how each of the programmable cells will emulate the user's logic. During a “program” mode, a configuration bitstream is provided to non-volatile memory, such as a read-only memory (ROM) (e.g. a programmable ROM (PROM), an erasable PROM (EPROM), or an electrically erasable PROM (EEPROM)) either external or internal to the programmable logic device. Each address is typically accessed by specifying its row and column addresses. During system power up of a “startup” mode, the configuration bits are successively loaded from the non-volatile memory into static random access memory (SRAM) configuration latches of a configuration logic block.
In addition to configuration memory, PLDs typically include other on-chip memory such as blocks of random access memory available for users to implement their designs. Memory is a common building block in many applications such as signal processing, filter designs, video processing, packet queuing and processing systems. Some of these applications require a large amount of memory. However, the amount of available memory on a PLD for implementing user designs beyond the memory required to enable the operation of the PLD may be limited. When implementing an application on a PLD, on-chip memory and off-chip memory are generally considered for use with the application. While a user of a PLD may use both on-chip memory and off-chip memory, there are a number of problems that a user may encounter when using either of these types of memories.
On-chip memories on a PLD are relatively small in size and considered as a dedicated and expensive resource. Low-end PLDs or PLDs in a small package could have a very limited amount of memory. In some scenarios, there may be some constraint on timing or routing of interconnects that prevents the full utilization of available on-chip memories. While off-chip memories may be used to supplement the on-chip memories, off-chip memories may not be available on every platform, and the memory size may be fixed or not easily extended. The architecture and available amount of on-chip memories vary across PLDs based on the device family and packaging. The timing/routing constraint affecting the amount of usable memory varies not only with devices, but also with designs. Similar problems exist when using off-chip memories. For instance, some platforms have a fixed, on-board, dual in-line memory module (DIMM) with a simple zero bit turnaround (ZBT) memory interface, while some have a complicated double data rate 2 (DDR2) interface that supports external DIMMs. Interfacing with off-chip memories such as DDR2 may be challenging. A memory controller is often needed to use off-chip memories, and different memory standards may require different controllers. The control and timing to perform a memory access may also vary across different standards.
The limitations in memory size and the variations of memory resources across platforms described above may further impact the user flexibility of a design to be implemented by a user. For example, a design for a PLD platform may need to be modified before it may be migrated to another PLD platform with less memory. The modification may involve reducing the size of memory buffers, or using a different memory controller in the design. Some other portions of the design, such as address/data bus widths, control logic, and pipeline stages, may also need be adjusted accordingly. These changes may be a burden to users, especially when they cannot be abstracted and automated.
Instead of storing application data in memory, some systems, such as hardware-in-the-loop (HITL) systems, dynamically stream data into the design running on a PLD. Although this approach overcomes the memory size limitation, it does not offer a good degree of abstraction and transparency to users. Users often need to consider the data streaming as part of the design by taking into account of the data transfer time, communication handshaking, data consumption pattern and timing. Therefore, dynamically streaming data changes the memory access model and requires modifications to the design.
Conventional software tools implementing hardware co-simulation support the concept of shared memory. A dual-port memory block is logically partitioned into two halves, where one half is accessed by the software application and the other half is accessed by the design running on the PLD. The software application manages the synchronization of the memory content in software and hardware by using a mutually exclusive locking mechanism. While the approach may be extended to overcome the memory size limitation by constantly updating the memory with new data, there are significant drawbacks with this approach. For example, one half of the dual memory block becomes unusable by the design. Also, the shared memory is not completely abstracted from the design. That is, users still need to interface the design with the shared memory appropriately, and use the control and locking correctly.
Accordingly, there is a need for an improved method of and system for implementing a circuit in a device having programmable logic.